// utility standard header
#ifndef _UTILITY_
#define _UTILITY_
#include <xstddef>
#include <iosfwd>
#include <type_traits>

_STD_BEGIN
		// TEMPLATE FUNCTION iter_swap (from <xutility>)
template<class _Ty> inline
	void swap(_Ty&, _Ty&)
		_NOEXCEPT_OP(is_nothrow_move_constructible<_Ty>::value
			&& is_nothrow_move_assignable<_Ty>::value);

template<class _FwdIt1,
	class _FwdIt2> inline
	void iter_swap(_FwdIt1 _Left, _FwdIt2 _Right)
	{	// swap *_Left and *_Right
	swap(*_Left, *_Right);
	}

		// TEMPLATE FUNCTION swap
template<class _Ty,
	size_t _Size> inline
	void swap(_Ty (&_Left)[_Size], _Ty (&_Right)[_Size])
		_NOEXCEPT_OP(_NOEXCEPT_OP(swap(*_Left, *_Right)))
	{	// exchange arrays stored at _Left and _Right
	if (&_Left != &_Right)
		{	// worth swapping, swap ranges
		_Ty *_First1 = _Left;
		_Ty *_Last1 = _First1 + _Size;
		_Ty *_First2 = _Right;
		for (; _First1 != _Last1; ++_First1, ++_First2)
			_STD iter_swap(_First1, _First2);
		}
	}

template<class _Ty> inline
	void swap(_Ty& _Left, _Ty& _Right)
		_NOEXCEPT_OP(is_nothrow_move_constructible<_Ty>::value
			&& is_nothrow_move_assignable<_Ty>::value)
	{	// exchange values stored at _Left and _Right
	_Ty _Tmp = _Move(_Left);
	_Left = _Move(_Right);
	_Right = _Move(_Tmp);
	}

		// TEMPLATE FUNCTION _Swap_adl
template<class _Ty> inline
	void _Swap_adl(_Ty& _Left, _Ty& _Right)
		_NOEXCEPT_OP(_NOEXCEPT_OP(swap(_Left, _Right)))
	{	// exchange values stored at _Left and _Right, using ADL
	swap(_Left, _Right);
	}

		// STRUCT piecewise_construct_t
struct piecewise_construct_t
	{	// tag type for pair tuple arguments
	};

 #if _HAS_CPP1X
_CONST_DATA piecewise_construct_t piecewise_construct{};
 #else /* _HAS_CPP1X */
_CONST_DATA piecewise_construct_t piecewise_construct =
	piecewise_construct_t();
 #endif /* _HAS_CPP1X */

		// TEMPLATE STRUCT pair

 #if _HAS_VARIADIC_TEMPLATES
template<class...>
	class tuple;

 #else /* _HAS_VARIADIC_TEMPLATES */

 #if _IS_EMBEDDED

 #else /* _IS_EMBEDDED */
template<class = _Nil, _MAX_CLASS_LIST>
	class tuple;
 #endif /* _IS_EMBEDDED */

 #endif /* _HAS_VARIADIC_TEMPLATES */

template<class _Ty1,
	class _Ty2>
	struct pair
	{	// store a pair of values
	typedef pair<_Ty1, _Ty2> _Myt;
	typedef _Ty1 first_type;
	typedef _Ty2 second_type;

	_CONST_FUN pair()
		: first(), second()
		{	// default construct
		}

	_CONST_FUN pair(const _Ty1& _Val1, const _Ty2& _Val2)
		: first(_Val1), second(_Val2)
		{	// construct from specified values
		}

 #if 0 < _MSC_VER
	pair(const pair&) = default;

	pair(_Myt&& _Right)
		: first(_STD forward<first_type>(_Right.first)),
			second(_STD forward<second_type>(_Right.second))
		{	// copy construct
		}

 #else /* 0 < _MSC_VER */
	pair(const pair&) = default;
	pair(pair&&) = default;
 #endif /* 0 < _MSC_VER */

 #if _HAS_NEW_SFINAE
	template<class _Other1,
		class _Other2,
		class = typename enable_if<is_convertible<const _Other1&, _Ty1>::value
			&& is_convertible<const _Other2&, _Ty2>::value,
			void>::type>
		_CONST_FUN pair(const pair<_Other1, _Other2>& _Right)
		: first(_Right.first), second(_Right.second)
		{	// construct from compatible pair
		}

 #else /* _HAS_NEW_SFINAE */
	template<class _Other1,
		class _Other2>
		_CONST_FUN pair(const pair<_Other1, _Other2>& _Right,
			typename enable_if<is_convertible<const _Other1&, _Ty1>::value
				&& is_convertible<const _Other2&, _Ty2>::value,
				void>::type ** = 0)
		: first(_Right.first), second(_Right.second)
		{	// construct from compatible pair
		}
 #endif /* _HAS_NEW_SFINAE */

	template<class _Other1,
		class _Other2>
		_Myt& operator=(const pair<_Other1, _Other2>& _Right)
		{	// assign from compatible pair
		first = _Right.first;
		second = _Right.second;
		return (*this);
		}

 #if _HAS_VARIADIC_TEMPLATES

 #if _HAS_DELEGATING_CONSTRUCTORS
	template<class _Tuple1,
		class _Tuple2,
		size_t... _Indexes1,
		size_t... _Indexes2> inline
		pair(_Tuple1& _Val1,
			_Tuple2& _Val2,
			integer_sequence<size_t, _Indexes1...>,
			integer_sequence<size_t, _Indexes2...>);

 #else /* _HAS_DELEGATING_CONSTRUCTORS */
	template<class _Ty,
		class _Tuple,
		size_t... _Indexes> inline
		typename remove_cv<_Ty>::type _Init(
			_Tuple&, integer_sequence<size_t, _Indexes...>);
 #endif /* _HAS_DELEGATING_CONSTRUCTORS */

	template<class... _Types1,
		class... _Types2> inline
		pair(piecewise_construct_t,
			tuple<_Types1...> _Val1,
			tuple<_Types2...> _Val2);

 #else /* _HAS_VARIADIC_TEMPLATES */
#define _PAIR_TUPLE_CONSTRUCTOR_DECL0( \
	TEMPLATE_LIST1, PADDING_LIST1, LIST1, C1, \
	TEMPLATE_LIST2, PADDING_LIST2, LIST2, C2) \
	TEMPLATE_LIST1(_CLASS_TYPE) \
		pair(piecewise_construct_t, \
			tuple<LIST1(_TYPE)>, \
			tuple<>);

_VARIADIC_EXPAND_0X_0(_PAIR_TUPLE_CONSTRUCTOR_DECL0)
#undef _PAIR_TUPLE_CONSTRUCTOR_DECL0

#define _PAIR_TUPLE_CONSTRUCTOR_DECL1( \
	TEMPLATE_LIST1, PADDING_LIST1, LIST1, C1, \
	TEMPLATE_LIST2, PADDING_LIST2, LIST2, C2) \
	template<LIST2(_CLASS_TYPEX)> \
		pair(piecewise_construct_t, \
			tuple<>, \
			tuple<LIST2(_TYPEX)>);

_VARIADIC_EXPAND_0_1X(_PAIR_TUPLE_CONSTRUCTOR_DECL1)
#undef _PAIR_TUPLE_CONSTRUCTOR_DECL1

#define _PAIR_TUPLE_CONSTRUCTOR_DECL2( \
	TEMPLATE_LIST1, PADDING_LIST1, LIST1, C1, \
	TEMPLATE_LIST2, PADDING_LIST2, LIST2, C2) \
	template<LIST1(_CLASS_TYPE), LIST2(_CLASS_TYPEX)> \
		pair(piecewise_construct_t, \
			tuple<LIST1(_TYPE)>, \
			tuple<LIST2(_TYPEX)>);

_VARIADIC_EXPAND_1X_1X(_PAIR_TUPLE_CONSTRUCTOR_DECL2)
#undef _PAIR_TUPLE_CONSTRUCTOR_DECL2
 #endif /* _HAS_VARIADIC_TEMPLATES */

 #if _HAS_RVALUE_REFERENCES

 #if _HAS_NEW_SFINAE
	template<class _Other1,
		class _Other2,
		class = typename enable_if<is_convertible<_Other1, _Ty1>::value
			&& is_convertible<_Other2, _Ty2>::value,
			void>::type>
		_CONST_FUN pair(_Other1&& _Val1, _Other2&& _Val2)
			_NOEXCEPT_OP((is_nothrow_constructible<_Ty1, _Other1&&>::value
				&& is_nothrow_constructible<_Ty2, _Other2&&>::value))
		: first(_STD forward<_Other1>(_Val1)),
				second(_STD forward<_Other2>(_Val2))
		{	// construct from moved values
		}

	template<class _Other1,
		class _Other2,
		class = typename enable_if<is_convertible<_Other1, _Ty1>::value
			&& is_convertible<_Other2, _Ty2>::value,
			void>::type>
		_CONST_FUN pair(pair<_Other1, _Other2>&& _Right)
			_NOEXCEPT_OP((is_nothrow_constructible<_Ty1, _Other1&&>::value
				&& is_nothrow_constructible<_Ty2, _Other2&&>::value))
		: first(_STD forward<_Other1>(_Right.first)),
			second(_STD forward<_Other2>(_Right.second))
		{	// construct from moved compatible pair
		}

 #else /* _HAS_NEW_SFINAE */
	template<class _Other1,
		class _Other2>
		_CONST_FUN pair(_Other1&& _Val1, _Other2&& _Val2,
			typename enable_if<is_convertible<_Other1, _Ty1>::value
				&& is_convertible<_Other2, _Ty2>::value,
				void>::type ** = 0)
			_NOEXCEPT_OP((is_nothrow_constructible<_Ty1, _Other1&&>::value
				&& is_nothrow_constructible<_Ty2, _Other2&&>::value))
		: first(_STD forward<_Other1>(_Val1)),
				second(_STD forward<_Other2>(_Val2))
		{	// construct from moved values
		}

	template<class _Other1,
		class _Other2>
		_CONST_FUN pair(pair<_Other1, _Other2>&& _Right,
			typename enable_if<is_convertible<_Other1, _Ty1>::value
				&& is_convertible<_Other2, _Ty2>::value,
				void>::type ** = 0)
			_NOEXCEPT_OP((is_nothrow_constructible<_Ty1, _Other1&&>::value
				&& is_nothrow_constructible<_Ty2, _Other2&&>::value))
		: first(_STD forward<_Other1>(_Right.first)),
			second(_STD forward<_Other2>(_Right.second))
		{	// construct from moved compatible pair
		}
 #endif /* _HAS_NEW_SFINAE */

	template<class _Other1,
		class _Other2>
		_Myt& operator=(pair<_Other1, _Other2>&& _Right)
		{	// assign from moved compatible pair
		first = _STD forward<_Other1>(_Right.first);
		second = _STD forward<_Other2>(_Right.second);
		return (*this);
		}

	_Myt& operator=(_Myt&& _Right)
		_NOEXCEPT_OP((is_nothrow_move_assignable<_Ty1>::value
			&& is_nothrow_move_assignable<_Ty2>::value))
		{	// assign from moved pair
		first = _STD forward<_Ty1>(_Right.first);
		second = _STD forward<_Ty2>(_Right.second);
		return (*this);
		}
 #endif /* _HAS_RVALUE_REFERENCES */

	void swap(_Myt& _Right)
		_NOEXCEPT_OP(_NOEXCEPT_OP(_Swap_adl(this->first, _Right.first))
			&& _NOEXCEPT_OP(_Swap_adl(this->second, _Right.second)))
		{	// exchange contents with _Right
		if (this != &_Right)
			{	// different, worth swapping
			_Swap_adl(first, _Right.first);
			_Swap_adl(second, _Right.second);
			}
		}

	_Myt& operator=(const _Myt& _Right)
		{	// assign from copied pair
		first = _Right.first;
		second = _Right.second;
		return (*this);
		}

	_Ty1 first;	// the first stored value
	_Ty2 second;	// the second stored value
	};

		// pair TEMPLATE FUNCTIONS
template<class _Ty1,
	class _Ty2> inline
	void swap(pair<_Ty1, _Ty2>& _Left, pair<_Ty1, _Ty2>& _Right)
		_NOEXCEPT_OP(_NOEXCEPT_OP(_Left.swap(_Right)))
	{	// swap _Left and _Right pairs
	_Left.swap(_Right);
	}

template<class _Ty1,
	class _Ty2> inline
	_CONST_FUN bool operator==(const pair<_Ty1, _Ty2>& _Left,
		const pair<_Ty1, _Ty2>& _Right)
	{	// test for pair equality
	return (_Left.first == _Right.first && _Left.second == _Right.second);
	}

template<class _Ty1,
	class _Ty2> inline
	_CONST_FUN bool operator!=(const pair<_Ty1, _Ty2>& _Left,
		const pair<_Ty1, _Ty2>& _Right)
	{	// test for pair inequality
	return (!(_Left == _Right));
	}

template<class _Ty1,
	class _Ty2> inline
	_CONST_FUN bool operator<(const pair<_Ty1, _Ty2>& _Left,
		const pair<_Ty1, _Ty2>& _Right)
	{	// test if _Left < _Right for pairs
	return (_Left.first < _Right.first ||
		(!(_Right.first < _Left.first) && _Left.second < _Right.second));
	}

template<class _Ty1,
	class _Ty2> inline
	_CONST_FUN bool operator>(const pair<_Ty1, _Ty2>& _Left,
		const pair<_Ty1, _Ty2>& _Right)
	{	// test if _Left > _Right for pairs
	return (_Right < _Left);
	}

template<class _Ty1,
	class _Ty2> inline
	_CONST_FUN bool operator<=(const pair<_Ty1, _Ty2>& _Left,
		const pair<_Ty1, _Ty2>& _Right)
	{	// test if _Left <= _Right for pairs
	return (!(_Right < _Left));
	}

template<class _Ty1,
	class _Ty2> inline
	_CONST_FUN bool operator>=(const pair<_Ty1, _Ty2>& _Left,
		const pair<_Ty1, _Ty2>& _Right)
	{	// test if _Left >= _Right for pairs
	return (!(_Left < _Right));
	}

	// TEMPLATE FUNCTION make_pair

 #if _HAS_RVALUE_REFERENCES
template<class _Ty1,
	class _Ty2> inline
	_CONST_FUN pair<typename _Unrefwrap<_Ty1>::type,
		typename _Unrefwrap<_Ty2>::type>
		make_pair(_Ty1&& _Val1, _Ty2&& _Val2)
	{	// return pair composed from arguments
	typedef pair<typename _Unrefwrap<_Ty1>::type,
		typename _Unrefwrap<_Ty2>::type> _Mypair;
	return (_Mypair(_STD forward<_Ty1>(_Val1),
		_STD forward<_Ty2>(_Val2)));
	}

 #else /* _HAS_RVALUE_REFERENCES */
template<class _Ty1,
	class _Ty2> inline
	_CONST_FUN pair<_Ty1, _Ty2> make_pair(_Ty1 _Val1, _Ty2 _Val2)
	{	// return pair composed from arguments
	return (pair<_Ty1, _Ty2>(_Val1, _Val2));
	}
 #endif /* _HAS_RVALUE_REFERENCES */

 #if _HAS_NAMESPACE
		// TEMPLATE OPERATORS
	namespace rel_ops
		{	// nested namespace to hide relational operators from std
template<class _Ty> inline
	bool operator!=(const _Ty& _Left, const _Ty& _Right)
	{	// test for inequality, in terms of equality
	return (!(_Left == _Right));
	}

template<class _Ty> inline
	bool operator>(const _Ty& _Left, const _Ty& _Right)
	{	// test if _Left > _Right, in terms of operator<
	return (_Right < _Left);
	}

template<class _Ty> inline
	bool operator<=(const _Ty& _Left, const _Ty& _Right)
	{	// test if _Left <= _Right, in terms of operator<
	return (!(_Right < _Left));
	}

template<class _Ty> inline
	bool operator>=(const _Ty& _Left, const _Ty& _Right)
	{	// test if _Left >= _Right, in terms of operator<
	return (!(_Left < _Right));
	}
		}
 #endif /* _HAS_NAMESPACE */
_STD_END

 #if _HAS_TR1
_STD_BEGIN
template<class _Ty,
	_INT_OR_SIZE_T _Size>
	class array;

	// TEMPLATE STRUCT tuple_size
template<class _Tuple>
	struct tuple_size
	{	// size of non-tuple
	_STATIC_ASSERT2(_Always_false<_Tuple>::value,
		"The C++ Standard doesn't define tuple_size for this type.");
	};

template<class _Ty,
	size_t _Size>
	struct tuple_size<array<_Ty, _Size> >
		: integral_constant<size_t, _Size>
	{	// struct to determine number of elements in array
	};

template<class _Ty1,
	class _Ty2>
	struct tuple_size<pair<_Ty1, _Ty2> >
	: integral_constant<size_t, 2>
	{	// size of pair
	};

 #if _HAS_VARIADIC_TEMPLATES
template<class... _Types>
	struct tuple_size<tuple<_Types...> >
	: integral_constant<size_t, sizeof...(_Types)>
	{	// size of tuple
	};

 #else /* _HAS_VARIADIC_TEMPLATES */
#define _CLASS_TUPLE_SIZE( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
template<class _Xarg0 _EX(C) LIST(_CLASS_TYPE)> \
	struct tuple_size<tuple<_Xarg0 _EX(C) LIST(_TYPE)> > \
	: integral_constant<size_t, _Sizeof<_Xarg0 _EX(C) LIST(_TYPE)>::value> \
	{	/* size of tuple */ \
	};

_VARIADIC_EXPAND_0X(_CLASS_TUPLE_SIZE, , , , )
#undef _CLASS_TUPLE_SIZE
 #endif /* _HAS_VARIADIC_TEMPLATES */

template<class _Tuple>
	struct tuple_size<const _Tuple>
	: tuple_size<_Tuple>
	{	// size of const tuple
	};

template<class _Tuple>
	struct tuple_size<volatile _Tuple>
	: tuple_size<_Tuple>
	{	// size of volatile tuple
	};

template<class _Tuple>
	struct tuple_size<const volatile _Tuple>
	: tuple_size<_Tuple>
	{	// size of const volatile tuple
	};

	// CLASS tuple_element (find element by index)
template<size_t _Index,
	class _Tuple>
	struct tuple_element
	{	// struct to enforce bounds checking
	_STATIC_ASSERT2(_Always_false<_Tuple>::value,
		"tuple_element index out of bounds");
	};

template<size_t _Idx,
	class _Ty,
	_INT_OR_SIZE_T _Size>
	struct tuple_element<_Idx, array<_Ty, _Size> >
	{	// struct to determine type of element _Idx in array
	tuple_element()
		{	// default construct
		_STATIC_ASSERT2(_Idx < _Size, "array index out of bounds");
		}

	typedef _Ty type;
	};

template<class _Ty1,
	class _Ty2>
	struct tuple_element<0, pair<_Ty1, _Ty2> >
	{	// struct to determine type of element 0 in pair
	typedef _Ty1 type;
	};

template<class _Ty1,
	class _Ty2>
	struct tuple_element<1, pair<_Ty1, _Ty2> >
	{	// struct to determine type of element 1 in pair
	typedef _Ty2 type;
	};

 #if _HAS_VARIADIC_TEMPLATES
template<class _This,
	class... _Rest>
	struct tuple_element<0, tuple<_This, _Rest...> >
	{	// select first element
	typedef _This type;
	typedef tuple<_This, _Rest...> _Ttype;
	};

template<size_t _Index,
	class _This,
	class... _Rest>
	struct tuple_element<_Index, tuple<_This, _Rest...> >
		: public tuple_element<_Index - 1, tuple<_Rest...> >
	{	// recursive tuple_element definition
	};

 #else /* _HAS_VARIADIC_TEMPLATES */
template<>
	struct tuple_element<0, tuple<> >
	{	// tuple_element backstop
	typedef int type;
	};

#define _CLASS_TUPLE_ELEMENT( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
template<class _This _EX(C) LIST(_CLASS_TYPE)> \
	struct tuple_element<0, tuple<_This _EX(C) LIST(_TYPE)> > \
	{	/* select first element */ \
	typedef _This type; \
	typedef typename add_lvalue_reference<const _This>::type _Ctype; \
	typedef typename add_lvalue_reference<_This>::type _Rtype; \
	typedef typename add_rvalue_reference<_This>::type _RRtype; \
	typedef tuple<_This _EX(C) LIST(_TYPE)> _Ttype; \
	}; \
template<size_t _Index, \
	class _This _EX(C) LIST(_CLASS_TYPE)> \
	struct tuple_element<_Index, tuple<_This _EX(C) LIST(_TYPE)> > \
		: public tuple_element<_Index - 1, tuple<LIST(_TYPE)> > \
	{	/* recursive tuple_element definition */ \
	}; \
template<size_t _Index \
	_EX(C) LIST(_CLASS_TYPE)> \
	struct tuple_element<_Index, tuple<_Nil _EX(C) LIST(_TYPE)> > \
		: public tuple_element<0, tuple<_Nil _EX(C) LIST(_TYPE)> > \
	{	/* tuple_element backstop */ \
	typedef int type; \
	};

_VARIADIC_EXPAND_0X(_CLASS_TUPLE_ELEMENT, , , , )
#undef _CLASS_TUPLE_ELEMENT
 #endif /* _HAS_VARIADIC_TEMPLATES */

template<size_t _Index,
	class _Tuple>
	struct tuple_element<_Index, const _Tuple>
		: public tuple_element<_Index, _Tuple>
	{	// tuple_element for const
	typedef tuple_element<_Index, _Tuple> _Mybase;
	typedef typename add_const<typename _Mybase::type>::type type;
	};

template<size_t _Index,
	class _Tuple>
	struct tuple_element<_Index, volatile _Tuple>
		: public tuple_element<_Index, _Tuple>
	{	// tuple_element for volatile
	typedef tuple_element<_Index, _Tuple> _Mybase;
	typedef typename add_volatile<typename _Mybase::type>::type type;
	};

template<size_t _Index,
	class _Tuple>
	struct tuple_element<_Index, const volatile _Tuple>
		: public tuple_element<_Index, _Tuple>
	{	// tuple_element for const volatile
	typedef tuple_element<_Index, _Tuple> _Mybase;
	typedef typename add_cv<typename _Mybase::type>::type type;
	};

 #if _HAS_TEMPLATE_ALIAS
template<size_t _Index,
	class _Tuple>
	using tuple_element_t = typename tuple_element<_Index, _Tuple>::type;
 #endif /* _HAS_TEMPLATE_ALIAS */

	// TUPLE INTERFACE TO pair
template<class _Ret,
	class _Pair> inline
	_CONST_FUN _Ret _Pair_get(_Pair& _Pr,
		integral_constant<size_t, 0>) _NOEXCEPT
	{	// get reference to element 0 in pair _Pr
	return (_Pr.first);
	}

template<class _Ret,
	class _Pair> inline
	_CONST_FUN _Ret _Pair_get(_Pair& _Pr,
		integral_constant<size_t, 1>) _NOEXCEPT
	{	// get reference to element 1 in pair _Pr
	return (_Pr.second);
	}

template<size_t _Idx,
	class _Ty1,
	class _Ty2> inline
	_CONST_FUN typename tuple_element<_Idx, pair<_Ty1, _Ty2> >::type&
		get(pair<_Ty1, _Ty2>& _Pr) _NOEXCEPT
	{	// get reference to element at _Idx in pair _Pr
	typedef typename tuple_element<_Idx, pair<_Ty1, _Ty2> >::type& _Rtype;
	return (_Pair_get<_Rtype>(_Pr, integral_constant<size_t, _Idx>()));
	}

template<class _Ty1,
	class _Ty2> inline
	_CONST_FUN _Ty1& get(pair<_Ty1, _Ty2>& _Pr) _NOEXCEPT
	{	// get reference to element _Ty1 in pair _Pr
	return (_STD get<0>(_Pr));
	}

template<class _Ty2,
	class _Ty1> inline
	_CONST_FUN _Ty2& get(pair<_Ty1, _Ty2>& _Pr) _NOEXCEPT
	{	// get reference to element _Ty2 in pair _Pr
	return (_STD get<1>(_Pr));
	}

template<size_t _Idx,
	class _Ty1,
	class _Ty2> inline
	_CONST_FUN const typename tuple_element<_Idx, pair<_Ty1, _Ty2> >::type&
		get(const pair<_Ty1, _Ty2>& _Pr) _NOEXCEPT
	{	// get const reference to element at _Idx in pair _Pr
	typedef const typename tuple_element<_Idx, pair<_Ty1, _Ty2> >::type&
		_Ctype;
	return (_Pair_get<_Ctype>(_Pr, integral_constant<size_t, _Idx>()));
	}

template<class _Ty1,
	class _Ty2> inline
	_CONST_FUN const _Ty1& get(const pair<_Ty1, _Ty2>& _Pr) _NOEXCEPT
	{	// get const reference to element _Ty1 in pair _Pr
	return (_STD get<0>(_Pr));
	}

template<class _Ty2,
	class _Ty1> inline
	_CONST_FUN const _Ty2& get(const pair<_Ty1, _Ty2>& _Pr) _NOEXCEPT
	{	// get const reference to element _Ty2 in pair _Pr
	return (_STD get<1>(_Pr));
	}

 #if _HAS_RVALUE_REFERENCES
template<size_t _Idx,
	class _Ty1,
	class _Ty2> inline
	_CONST_FUN typename tuple_element<_Idx, pair<_Ty1, _Ty2> >::type&&
		get(pair<_Ty1, _Ty2>&& _Pr) _NOEXCEPT
	{	// get rvalue reference to element at _Idx in pair _Pr
	typedef typename tuple_element<_Idx, pair<_Ty1, _Ty2> >::type&& _RRtype;
	return (_STD forward<_RRtype>(_STD get<_Idx>(_Pr)));
	}

template<class _Ty1,
	class _Ty2> inline
	_CONST_FUN _Ty1&& get(pair<_Ty1, _Ty2>&& _Pr) _NOEXCEPT
	{	// get rvalue reference to element _Ty1 in pair _Pr
	return (_STD get<0>(_STD move(_Pr)));
	}

template<class _Ty2,
	class _Ty1> inline
	_CONST_FUN _Ty2&& get(pair<_Ty1, _Ty2>&& _Pr) _NOEXCEPT
	{	// get rvalue reference to element _Ty2 in pair _Pr
	return (_STD get<1>(_STD move(_Pr)));
	}
 #endif /* _HAS_RVALUE_REFERENCES */

	// TEMPLATE FUNCTION exchange

 #if _HAS_NEW_SFINAE
template<class _Ty,
	class _Other = _Ty> inline
	_Ty exchange(_Ty& _Val, _Other _REFREF _New_val)
	{	// assign _New_val to _Val, return previous _Val
	_Ty _Old_val = _STD move(_Val);
	_Val = _STD forward<_Other>(_New_val);
	return (_Old_val);
	}

 #else /* _HAS_NEW_SFINAE */
template<class _Ty> inline
	_Ty exchange(_Ty& _Val, _Ty _REFREF _New_val)
	{	// assign _New_val to _Val, return previous _Val
	_Ty _Old_val = _STD move(_Val);
	_Val = _STD forward<_Ty>(_New_val);
	return (_Old_val);
	}

template<class _Ty,
	class _Other> inline
	_Ty exchange(_Ty& _Val, _Other _REFREF _New_val)
	{	// assign _New_val to _Val, return previous _Val
	_Ty _Old_val = _STD move(_Val);
	_Val = _STD forward<_Other>(_New_val);
	return (_Old_val);
	}
 #endif /* _HAS_NEW_SFINAE */
_STD_END
 #endif /* _HAS_TR1 */

 #if _HAS_TR1_IMPORTS
_STD_BEGIN
namespace tr1 {	// TR1 additions
using _STD get;
using _STD tuple_element;
using _STD tuple_size;
}	// namespace tr1
_STD_END
 #endif /* _HAS_TR1_IMPORTS */

#endif /* _UTILITY_ */

/*
 * Copyright (c) by P.J. Plauger. All rights reserved.
 * Consult your license regarding permissions and restrictions.
V6.50:1422 */
